package com.bc.plugin.redis.hibernate.help;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;

public class RedisTimestamp {
	private static final Logger log = LoggerFactory.getLogger(RedisTimestamp.class);
	private static final int BIN_DIGITS = 12;
	private static final short ONE_MS = 1 << BIN_DIGITS;

	public static long nextTimestamp(RedisAtomicLong redisTimestamp) {
		int runs = 0;
		while (true) {
			long base = SlewClock.timeMillis() << BIN_DIGITS;
			long maxValue = base + ONE_MS - 1;
			for (long current = redisTimestamp.get(), update = Math.max(base,
					current + 1); update < maxValue; current = redisTimestamp
							.get(), update = Math.max(base, current + 1)) {
				if (redisTimestamp.compareAndSet(current, update)) {// 防止其他分布式项目并发执行
					if (runs > 1) {
						log.info("redisTimestamp Thread spin-waits on time to pass. Looped {} times", runs);
					}
					return update;
				}
			}
			++runs;
		}
	}
}
